package com.cloudbroker.bcs.platform.ltb.middle.bizservice.impl;

import com.alibaba.fastjson.JSON;
import com.cloudbroker.bcs.common.configure.ConfigUtil;
import com.cloudbroker.bcs.common.entity.HSBCPSBackVO;
import com.cloudbroker.bcs.common.util.ExceptionMsgUtil;
import com.cloudbroker.bcs.common.util.VOUtil;
import com.cloudbroker.bcs.csvc.lightinvesting.api.entity.CompayApplyQryResult;
import com.cloudbroker.bcs.csvc.lightinvesting.api.t2service.LedSecT2Service;
import com.cloudbroker.bcs.csvc.lightinvesting.api.vo.request.cashTransactions.CompayApplyForm;
import com.cloudbroker.bcs.csvc.lightinvesting.api.vo.request.cashTransactions.CompayApplyQryForm;
import com.cloudbroker.bcs.csvc.lightinvesting.api.vo.request.cashTransactions.CompayConfirmForm;
import com.cloudbroker.bcs.csvc.lightinvesting.api.vo.request.cashTransactions.CompayIdentifyForm;
import com.cloudbroker.bcs.csvc.lightinvesting.api.vo.response.CompayApplyQryBackVo;
import com.cloudbroker.bcs.csvc.lightinvesting.api.vo.response.CompayApplyVo;
import com.cloudbroker.bcs.csvc.lightinvesting.api.vo.response.CompayConfirmVo;
import com.cloudbroker.bcs.csvc.lightinvesting.api.vo.response.CompayIdentifyVo;
import com.cloudbroker.bcs.platform.ltb.bizapi.constants.HSBCPSErrorCodes;
import com.cloudbroker.bcs.platform.ltb.bizapi.constants.PingPlusType;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.base.vo.BrokerVO;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.pay.PingPlusPayBizService;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.pay.back.PayRefundBack;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.pay.back.PingPlusPayApplyBack;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.pay.vo.*;
import com.cloudbroker.bcs.platform.ltb.bizapi.service.push.vo.TagsAddForm;
import com.cloudbroker.bcs.platform.ltb.middle.entity.UserEntity;
import com.cloudbroker.bcs.platform.ltb.middle.model.UserCache;
import com.cloudbroker.bcs.platform.ltb.middle.service.PushService;
import com.cloudbroker.bcs.platform.ltb.middle.util.PingPlusUtil;
import com.cloudbroker.bcs.platform.ltb.middle.util.UserTokenUtil;
import com.pingplusplus.model.Charge;
import com.pingplusplus.model.Refund;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by daibd19671 on 2016/10/28.
 */
@Service
public class PingPlusPayBizServiceImpl implements PingPlusPayBizService {

    @Resource
    private LedSecT2Service ledSecT2Service;
    @Resource
    private PushService pushService;

    private Logger logger = LoggerFactory.getLogger(PingPlusPayBizServiceImpl.class);

    public PingPlusPayApplyBack func_ping_pay_apply(PingPlusPayApplyForm form) {
        //后台获取流水号
        CompayApplyForm compayApplyForm = new CompayApplyForm();
        compayApplyForm.setCombi_code(form.getCombi_code());
        compayApplyForm.setAdviser_id(form.getAdviser_id());
        compayApplyForm.setCompay_channel("0");
        compayApplyForm.setPartner_id(ConfigUtil.getString(form.getCompany_id(),"wx.app.partnerId",""));
        compayApplyForm.setMoney_type("CNY");
        compayApplyForm.setOccur_balance((double)form.getOccur_balance()/100);
        compayApplyForm.setChannel_id(form.getChannel_id());
        compayApplyForm.setRemark(form.getDescription());
        compayApplyForm.setOp_branch_no(form.getOp_branch_no());
        compayApplyForm.setOp_entrust_way(form.getOp_entrust_way());
        compayApplyForm.setOp_station(form.getOp_station());
        compayApplyForm.setBranch_no(form.getBranch_no());
        compayApplyForm.setPassword(form.getPassword());
        compayApplyForm.setPassword_type(form.getPassword_type());
        compayApplyForm.setUser_token(form.getUser_token());
        compayApplyForm.setUser_id(form.getUser().getUser_id()+"");
        CompayApplyVo compayApplyVo = ledSecT2Service.func_compay_apply(compayApplyForm);
        if(!"0".equals(compayApplyVo.getError_no())){
            return VOUtil.genErrorResult(compayApplyVo.getError_no(),compayApplyVo.getError_info(),PingPlusPayApplyBack.class);
        }

        //ping++ 创建charge对象
        Map<String, Object> chargeMap = new HashMap<String, Object>();
        chargeMap.put("amount", form.getOccur_balance());//订单总金额, 人民币单位：分
        chargeMap.put("currency", "cny");
        chargeMap.put("subject", form.getSubject());
        chargeMap.put("body", form.getBranch_no());
        chargeMap.put("order_no", compayApplyVo.getPartner_serial_no());// 推荐使用 8-20 位，要求数字或字母，不允许其他字特殊字符
        chargeMap.put("channel", PingPlusType.values()[form.getPay_channel()]);// 支付使用的第三方支付渠道，请参考：https://www.pingxx.com/api#api-c-new
        chargeMap.put("client_ip",form.getClient_ip()); // 发起支付请求客户端的 IP 地址，格式为 IPV4，如: 127.0.0.1
        chargeMap.put("open_id",form.getOpen_id());
        Charge charge = null;
        try {
            charge = PingPlusUtil.createCharge(chargeMap);
        } catch (Exception e) {
            try {
                String errorMsg = ExceptionMsgUtil.getExceptionMsg(e);
                return VOUtil.genErrorResult(HSBCPSErrorCodes.PayErrorInfo.PAY_APPLY_ERROR,errorMsg,PingPlusPayApplyBack.class);
            }catch (Exception e1){
                e1.printStackTrace();
            }
        }
        CompayIdentifyForm compayIdentifyForm = new CompayIdentifyForm();
        compayIdentifyForm.setOp_branch_no(form.getOp_branch_no());
        compayIdentifyForm.setOp_entrust_way(form.getOp_entrust_way());
        compayIdentifyForm.setOp_station(form.getOp_station());
        compayIdentifyForm.setBranch_no(form.getBranch_no());
        compayIdentifyForm.setPartner_id(ConfigUtil.getString(form.getCompany_id(),"wx.app.partnerId",""));
        compayIdentifyForm.setChannel_serial_no(charge.getTransactionNo());
        compayIdentifyForm.setPartner_serial_no(charge.getOrderNo());
        compayIdentifyForm.setPay_param(JSON.toJSONString(charge));
        compayIdentifyForm.setPay_status("2");
        compayIdentifyForm.setUser_token(form.getUser_token());
        compayIdentifyForm.setClient_marked(charge.getId());
        CompayIdentifyVo compayIdentifyVo = ledSecT2Service.func_compay_identify(compayIdentifyForm);
        if(!"0".equals(compayIdentifyVo.getError_no())){
            return VOUtil.genErrorResult(compayIdentifyVo.getError_no(),compayIdentifyVo.getError_info(),PingPlusPayApplyBack.class);
        }
        return VOUtil.setSuccessResult(new PingPlusPayApplyBack(JSON.toJSONString(charge)));
    }


    public PingPlusPayApplyBack func_ping_pay_oper(PingPlusPayOper form){
        //ping++ 创建charge对象
        Map<String, Object> chargeMap = new HashMap<String, Object>();
        chargeMap.put("amount", form.getOccur_balance());//订单总金额, 人民币单位：分
        chargeMap.put("currency", "cny");
        chargeMap.put("subject", form.getSubject());
        chargeMap.put("body", form.getBranch_no());
        chargeMap.put("order_no", form.getPartner_serial_no());// 推荐使用 8-20 位，要求数字或字母，不允许其他字特殊字符
        chargeMap.put("channel", PingPlusType.values()[form.getPay_channel()]);// 支付使用的第三方支付渠道，请参考：https://www.pingxx.com/api#api-c-new
        chargeMap.put("client_ip",form.getClient_ip()); // 发起支付请求客户端的 IP 地址，格式为 IPV4，如: 127.0.0.1
        chargeMap.put("open_id",form.getOpen_id());
        Charge charge = null;
        try {
            charge = PingPlusUtil.createCharge(chargeMap);
        } catch (Exception e) {
            try {
                String errorMsg = ExceptionMsgUtil.getExceptionMsg(e);
                return VOUtil.genErrorResult(HSBCPSErrorCodes.PayErrorInfo.PAY_APPLY_ERROR,errorMsg,PingPlusPayApplyBack.class);
            }catch (Exception e1){
                e1.printStackTrace();
            }
        }
        CompayIdentifyForm compayIdentifyForm = new CompayIdentifyForm();
        compayIdentifyForm.setOp_branch_no(form.getOp_branch_no());
        compayIdentifyForm.setOp_entrust_way(form.getOp_entrust_way());
        compayIdentifyForm.setOp_station(form.getOp_station());
        compayIdentifyForm.setBranch_no(form.getBranch_no());
        compayIdentifyForm.setPartner_id(ConfigUtil.getString(form.getCompany_id(),"wx.app.partnerId",""));
        compayIdentifyForm.setChannel_serial_no(charge.getTransactionNo());
        compayIdentifyForm.setPartner_serial_no(charge.getOrderNo());
        compayIdentifyForm.setPay_param(JSON.toJSONString(charge));
        compayIdentifyForm.setPay_status("2");
        compayIdentifyForm.setUser_token(form.getUser_token());
        compayIdentifyForm.setClient_marked(charge.getId());
        CompayIdentifyVo compayIdentifyVo = ledSecT2Service.func_compay_identify(compayIdentifyForm);
        if(!"0".equals(compayIdentifyVo.getError_no())){
            return VOUtil.genErrorResult(compayIdentifyVo.getError_no(),compayIdentifyVo.getError_info(),PingPlusPayApplyBack.class);
        }
        return VOUtil.setSuccessResult(new PingPlusPayApplyBack(JSON.toJSONString(charge)));
    }


    public HSBCPSBackVO func_cancel_pay_apply(PayCancelForm form){
        CompayConfirmForm compayConfirmForm = new CompayConfirmForm();
        compayConfirmForm.setPartner_id(ConfigUtil.getString("20020","wx.app.partnerId","0"));
        compayConfirmForm.setPartner_serial_no(form.getPartner_serial_no());
        compayConfirmForm.setHsepay_order_no("0");
        compayConfirmForm.setPay_status("7");
        compayConfirmForm.setOp_branch_no(form.getOp_branch_no());
        compayConfirmForm.setOp_entrust_way(form.getOp_entrust_way());
        compayConfirmForm.setOp_station(form.getOp_station());
        compayConfirmForm.setBranch_no(form.getBranch_no());
        compayConfirmForm.setCompany_id("20020");
        compayConfirmForm.setSendercomp_id("20020");
        compayConfirmForm.setUser_token(form.getUser_token());
        CompayConfirmVo compayConfirmVo = ledSecT2Service.func_compay_confirm(compayConfirmForm);
        if(!"0".equals(compayConfirmVo.getError_no())){
            return VOUtil.genErrorResult(compayConfirmVo.getError_no(),compayConfirmVo.getError_info(),PingPlusPayApplyBack.class);
        }
        return VOUtil.setSuccessResult(new HSBCPSBackVO());
    }


    public HSBCPSBackVO func_webhooks_callback(WebhooksForm form) throws RuntimeException{
        String signature =form.getSignature();
        String webhooksRawPostData = form.getWebhooksRawPostData();
        System.out.println(webhooksRawPostData);
        if(!PingPlusUtil.verifyData(webhooksRawPostData,signature)){
            return VOUtil.genErrorResultVo("500");
        }
        WebhooksEvent event = JSON.parseObject(webhooksRawPostData,WebhooksEvent.class);
        CompayConfirmVo compayConfirmVo=null;
        //目前只处理支付成功与退款成功的回调
        CompayConfirmForm compayConfirmForm = new CompayConfirmForm();
        if("refund.succeeded".equals(event.getType())){
            Refund refund =JSON.parseObject(JSON.toJSONString(event.getData().getObject()),Refund.class);
            Map<String, Object> metadata= refund.getMetadata();
            compayConfirmForm.setPartner_id(ConfigUtil.getString("20020","wx.app.partnerId","0"));
            compayConfirmForm.setPartner_serial_no(metadata.get("partner_serial_no").toString());
            compayConfirmForm.setHsepay_order_no(refund.getOrderNo());
            if(refund.getSucceed()){
                compayConfirmForm.setPay_status("3");
            }
        }else if("charge.succeeded".equals(event.getType())){
            Charge charge=JSON.parseObject(JSON.toJSONString(event.getData().getObject()),Charge.class);
            compayConfirmForm.setPartner_id(ConfigUtil.getString("20020","wx.app.partnerId","0"));
            compayConfirmForm.setPartner_serial_no(charge.getOrderNo());
            compayConfirmForm.setHsepay_order_no(charge.getTransactionNo());
            if(charge.getPaid()){
                compayConfirmForm.setPay_status("3");
            }

        }
        compayConfirmForm.setCompany_id("20020");
        compayConfirmForm.setSendercomp_id("20020");
        UserCache userCache = new UserCache();
        BrokerVO brokerVO = new BrokerVO();
        brokerVO.setCompany_id("20020");
        brokerVO.setSendercomp_id("20020");
        userCache.setBrokerVO(brokerVO);
        String user_token = UserTokenUtil.addUserToken(userCache);
        compayConfirmForm.setUser_token(user_token);
        compayConfirmVo = ledSecT2Service.func_compay_confirm(compayConfirmForm);
        if(VOUtil.isSuccess(compayConfirmVo)){
            //绑定标签
            CompayApplyQryForm compayApplyQryForm = new CompayApplyQryForm();
            compayApplyQryForm.setPartner_serial_no(compayConfirmForm.getPartner_serial_no());
            compayApplyQryForm.setSendercomp_id("20020");
            CompayApplyQryBackVo compayApplyQryBackVo = ledSecT2Service.func_compay_apply_qry(compayApplyQryForm);
            if(VOUtil.isSuccess(compayApplyQryBackVo)
                    && compayApplyQryBackVo.getData_list()!=null && compayApplyQryBackVo.getData_list().size()>0){
                CompayApplyQryResult compayApplyQryResult = compayApplyQryBackVo.getData_list().get(0);
                TagsAddForm tagsAddForm = new TagsAddForm();
                tagsAddForm.setCompany_id("20020");
                tagsAddForm.setSendercomp_id("20020");
                if(compayApplyQryResult.getCom_order_type().equals("3")){
                    //达人签约
                    tagsAddForm.setUser_id(Long.valueOf(compayApplyQryResult.getUser_id()));
                    tagsAddForm.setTag(compayApplyQryResult.getAdviser_id());
                    pushService.xinanTagsAdd(tagsAddForm);
                }else if(compayApplyQryResult.getCom_order_type().equals("1")){
                    //组合关注
                    tagsAddForm.setUser_id(Long.valueOf(compayApplyQryResult.getUser_id()));
                    tagsAddForm.setTag(compayApplyQryResult.getCombi_code());
                    pushService.xinanTagsAdd(tagsAddForm);
                }
            }
        }
        if(!"0".equals(compayConfirmVo.getError_no())){
            throw new RuntimeException("后台支付通知失败，错误信息"+compayConfirmVo.getError_info());
        }
        return VOUtil.genSuccessBackVo();

    }


    public PayRefundBack func_ping_pay_refund(PayRefundForm form){
        Refund refund = null;
        PayRefundBack payRefundBack = new PayRefundBack();
        Map<String,Object> paramMap = new HashMap<>();
        if(form.getAmount()>0 && form.getAmount()<1000000000){
            paramMap.put("amount",form.getAmount());
        }
        if(StringUtils.isBlank(form.getDescription())) {
            paramMap.put("description", form.getClient_marked() + "退款");
        }else{
            paramMap.put("description", form.getDescription());
        }
        Map<String,Object> metadata = new HashMap<>();
        metadata.put("partner_serial_no",form.getPartner_serial_no());
        paramMap.put("metadata",metadata);
        if(org.apache.commons.lang.StringUtils.isNotBlank(form.getFunding_source())){
            paramMap.put("funding_source",form.getFunding_source());
        }
        try {
            refund = PingPlusUtil.refund(form.getClient_marked(),paramMap);
        } catch (Exception e) {
            try {
                String errorMsg = ExceptionMsgUtil.getExceptionMsg(e);
                payRefundBack.setPay_status("2");
                payRefundBack.setError_no(HSBCPSErrorCodes.PayErrorInfo.PAY_REFUND_ERROR);
                payRefundBack.setError_info(errorMsg);
                return VOUtil.setJsonpResult(payRefundBack,"");
            }catch (Exception e1){
                e1.printStackTrace();
            }
        }

        if(refund != null && StringUtils.isBlank(refund.getFailureCode())){
            payRefundBack.setOccur_blance(refund.getAmount()/100);
            payRefundBack.setPartner_serial_no(form.getPartner_serial_no());
            payRefundBack.setHsepay_order_no(refund.getOrderNo());
            payRefundBack.setOrgn_serial_no(refund.getChargeOrderNo());
            payRefundBack.setPartner_id(form.getPartner_id());
            payRefundBack.setPay_status("2");
            return VOUtil.setSuccessResult(payRefundBack);
        }else{
            payRefundBack.setPay_status("7");
            payRefundBack.setError_no(HSBCPSErrorCodes.PayErrorInfo.PAY_REFUND_ERROR);
            payRefundBack.setError_info(refund.getFailureMsg());
            return VOUtil.setJsonpResult(payRefundBack,"");
        }

    }

}
